<?php

namespace App\Services\Draw\PoolGroupObject;

use App\Exceptions\BasicException;
use App\Jobs\QiPao\Draw\SeniorDrawFullGiftJob;
use App\Services\Draw\DrawConst\CacheKey;
use App\Services\Draw\DrawFactory;
use Illuminate\Support\Collection;

/**
 *
 * @author wrh
 */
class SeniorPublicPoolGroup extends PublicPoolGroup
{

    public function getPoolPrizeList($user)
    {
        return new Collection();
    }

    public function checkDrawRoundPrizeCount(Collection $poolPrizeList, int $drawCount, $user, $poolConfig)
    {

        $templatePrizeCount = $this->poolTemplateModel->sumTemplateCount(['group_id' => $this->group_id]);
        $prizesLength       = $this->redisObject->llen($this->cachePrefix . "prizeList_" . $this->tag);
        //获取模板礼物总数 2023.12.10由 /2 改为/10  百分之50 改为百分之10
        if ($templatePrizeCount / 10 + $drawCount > $prizesLength) {
            return false;
        }
        return true;
    }

    public function createNextRoundPrizes(Collection $templatePrizes, $user, int $drawCount)
    {
        if (!$this->redisObject->set($this->cachePrefix . "fullPollLock_" . $this->tag, 1, 'ex', $this->gameLockTime, 'nx')) {
            return null;
        }
        try {
            $prizesLength = $this->redisObject->llen($this->cachePrefix . "prizeList_" . $this->tag);
            //判断奖池剩余数量 如果这次抽奖数量都不足够则同步补充礼物
            if (false && $drawCount < $prizesLength) {

                $poolGroupInfo = ['group_id' => $this->group_id, 'pool_id' => $this->pool_id, 'tag' => $this->tag];
                dispatch(new SeniorDrawFullGiftJob($templatePrizes, $poolGroupInfo, $this->cachePrefix))->onQueue('isGamePush');
            } else {
                if (!$this->createNextRoundPrizesWeight($templatePrizes)) {
                    return [];
                }
            }

            //补充补池金额
            $this->addPoolRepo->checkPool($this->tag, 2, $this->group_id);
        } catch (\Exception $e) {
            throw  $e;
        }
        // 清空本轮礼物总数
//        $this->poolPrizeModel->updateData(['group_id' => $this->group_id], ['template_count' => 0]);
//        $this->poolPrizeModel->appendPrizes($this, $templatePrizes);
    }

    public function decPoolPrize(array $drawPrizes)
    {
        $this->poolPrizeModel->batchDecPrizesByGroup($this, $drawPrizes);
        return true;
    }

    //用户是否可以强制触发碎片池
    protected function forceTriggerFragment($user, $poolConfig)
    {
        //  强制触发未开启 ||  今日已触发  ||  日投入不达标  ||  碎片池数量不够
        if (!$poolConfig['fragment_open_trigger']
            || $this->getFragmentForceTriggerInfo($user['user_id']) > 0
            || $user['input_date'] < $poolConfig['fragment_user_money']
            || $this->redisObject->get(CacheKey::getFragmentPoolNumsKey($this->privateKey)) < $poolConfig['fragment_pool_coin_min']) {
            return false;
        }
        return true;
    }

    //可以触发进行数据处理
    public function setFragmentForceTriggerInfo($user, $poolConfig)
    {
        $this->getFragmentForceTriggerInfo();//避免未初始化

        $redis_key = CacheKey::getFragmentForceTriggerKey($this->privateKey);
        $this->redisObject->hincrby($redis_key, $user->user_id, 1);
        $all_num = $this->redisObject->hincrby($redis_key, 'all', 1);
        //强制触发后，重新计算下一次需要触发的数量
        $fragment_daily_ratio_next = round($poolConfig['fragment_daily_ratio'] / 100 , 2) + 1;
        $ratio = round(pow($fragment_daily_ratio_next, $all_num), 2);
        $mset = [
            'fragment_next_num'      => floor($poolConfig['fragment_daily_num'] * $ratio),
            'fragment_daily_add_num' => 0,
        ];
        $this->redisObject->hmset($redis_key, $mset);
    }

    public function getFragmentForceTriggerInfo($field = '')
    {
        $redis_key = CacheKey::getFragmentForceTriggerKey($this->privateKey);
        if ($this->redisObject->exists($redis_key)) {
            if (empty($field)) {
                return $this->redisObject->hgetall($redis_key);
            }
            return $this->redisObject->hget($redis_key, $field) ?: '';
        }
        $poolConfig = (new DrawFactory())->make($this->privateKey)->getPoolConfig();
        $data = [
            'fragment_next_num'      => $poolConfig['fragment_daily_num'],
            'fragment_daily_add_num' => 0,
        ];
        $this->redisObject->hmset($redis_key, $data);
        $this->redisObject->expire($redis_key, 86400);
        if (empty($field)) {
            return $data['field'] ?? '';
        }
        return $data;
    }

    public function execFragmentGroup($user, $poolGroup)
    {
        $fragment_group_list = (new DrawFactory())->make($this->privateKey)->getFragmentGroupList();
        if (empty($fragment_group_list)) {
            return [];
        }

        $rand = $fragment_group_list[array_rand($fragment_group_list)];
        if ($rand['other_num'] < 0) {
            return [];
        }
        $gift_template_ids = $rand['gift_template_ids'];

        $pool_gift_template_ids = $this->poolTemplateModel->where('group_id', $poolGroup->group_id)->pluck('gift_template_id')->toArray();

        $other_gift_template_ids = $this->giftTemplateModel
            ->from($this->giftTemplateModel->getTable().' as a')
            ->join(app('model_gift')->getTable().' as b', 'a.gift_id', '=', 'b.id')
            ->whereIn('a.id', $pool_gift_template_ids)
            ->whereNotIn('a.id', $gift_template_ids)
            ->selectRaw('a.id,b.price')
            ->limit($rand['other_num'])
            ->orderby('b.price')
            ->pluck('id')
            ->toArray();

        $gift_template_ids = array_merge($gift_template_ids, $other_gift_template_ids);

        $group_id = $poolGroup->group_id;
        $redis_key = $this->cachePrefix . "prizeList_" . $this->tag;
        $allExist = true;
        $appoint_groupPrizes = [];
        foreach ($gift_template_ids as $gt_id) {
            $appoint_groupPrizes[] = $appoint_key = $group_id .'_'. $gt_id;
            if ($this->redisObject->executeRaw(['LPOS', $redis_key, $appoint_key]) === NULL) {
                $allExist = false;
                break;
            }
        }
        $result_gift_num = 0;
        if ($allExist) {
            $result = $this->redisObject->transaction(function ($redis) use ($gift_template_ids, $group_id, $redis_key) {
                foreach ($gift_template_ids as $gt_id) {
                    $appoint_key = $group_id .'_'. $gt_id;
                    $redis->lrem($redis_key, 1, $appoint_key);
                }
            });
            $result = array_count_values($result);
            $result_gift_num = $result[1];
            if ($result_gift_num !== count($gift_template_ids)) {
                return [];
            }

        }
        return [
            'result_gift_num' => $result_gift_num,
            'appoint_groupPrizes' => $appoint_groupPrizes,
        ];

    }
}
